//
//  CZPublishViewController.swift
//  Weibo24
//
//  Created by apple on 16/3/4.
//  Copyright © 2016年 apple. All rights reserved.
//

/*
    1. 有思路
    2. 罗列一个大概的步骤
    3. 遇到问题 
    4. 针对遇到的问题,解决问题
*/

import UIKit
import SnapKit
import AFNetworking
import SVProgressHUD

/*
    1.分析界面
    2.分析功能
*/
/*
    1. 标题
    2. 占位文字
    3. 键盘
*/

let holderString = "下雨天和巧克力搭配更好吃哦"

// 都要去遵守 这个2个协议 UIImagePickerControllerDelegate,UINavigationControllerDelegate
class CZPublishViewController: UIViewController ,UITextViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{

    //定义一个成员变量来记录 底部toolBar的约束
    var bottomConstrant: Constraint?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.whiteColor()
        
        setupNav()
        
        setupTextView()
        
        
        setupToolBar()
        
        /*
        UIKeyboardWillChangeFrameNotification -- 还没有改变
        UIKeyboardDidChangeFrameNotification -- 已经改变
        */
        //添加键盘通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "changeToolBarFrame:", name: UIKeyboardWillChangeFrameNotification, object: nil)
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "inputEmoticon:", name: kNotificationEmoticonTransform, object: nil)

    }

   //MARK:--设置Nav
    
    private func setupNav(){
    
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "dismiss")
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "发布", style: UIBarButtonItemStyle.Plain, target: self, action: "publish")
        
        navigationItem.rightBarButtonItem?.enabled = false
        
        /*
        
            1.放2个label -- 自己试试
            2.一个label实现
        */
        // 标题
        
        let titleLabel = UILabel(frame: CGRectMake(0,0,200,44))
        
        titleLabel.numberOfLines = 0
        
//        titleLabel.text = "发布微博\n\(CZUserViewModel.shareInstance.model?.screen_name ?? "")"
        
        titleLabel.textAlignment = .Center
        
        let str = "发布微博\n\(CZUserViewModel.shareInstance.model?.screen_name ?? "")"
        // NSAttributedString -- 这个是不可变的,我们要修改属性的话,需要用到
        //NSMutableAttributedString
        let attribute = NSMutableAttributedString(string: str)
        
        // 添加属性
        // 修改 发布微博 4个字的属性
        attribute.addAttributes([NSFontAttributeName: UIFont.systemFontOfSize(15)], range: NSMakeRange(0, 4))
        // 修改 名字 的字属性
        attribute.addAttributes([NSFontAttributeName: UIFont.systemFontOfSize(13),NSForegroundColorAttributeName: UIColor.orangeColor()], range: NSMakeRange(4, str.characters.count - 4))
        
        titleLabel.attributedText  = attribute
        
//        titleLabel.textColor = UIColor.orangeColor()
        
       navigationItem.titleView = titleLabel
    }
    
    //MARK:--Nav的按钮方法
   @objc private func dismiss(){
    
        dismissViewControllerAnimated(true) { () -> Void in
            
    }
    
    }
    
   @objc private func publish(){
    
        // 需要判断发布微博里有没有图片
        if photoView.allImages().count > 0 {
            publishPhoto()
        } else {
            publishText()
        }
    
    
    }
    
    private func publishText(){
    
        /*
        第一步: 获取发布的字符串 如果是 你号+笑脸 -> 你号[微笑]
        第二步: 调用接口发布数据
        */
        
        //    printLog(textView.attributedText) // 你好￼
        /*
        第一个参数: nsrange -- 字符串的长度
        第二个参数: 枚举,选一个默认值
        
        */
        var publishString: String = ""
        
        textView.attributedText.enumerateAttributesInRange(NSMakeRange(0, textView.attributedText.length), options: []) { (data:[String : AnyObject], range:NSRange, _) -> Void in
            
            //        printLog(data)
            //
            //        printLog(range)
            
            if let attachment = data["NSAttachment"] as? CZTextAttachment{
                printLog("\(attachment.emoticon?.chs)")
                publishString += attachment.emoticon!.chs!
                
            } else {
                printLog("这个range里的是 文字")
                let str = (self.textView.text as NSString).substringWithRange(range)
                printLog(str)
                publishString += str
            }
            
        }
        
        printLog(publishString)
        
        
        let afn = AFHTTPSessionManager()
        
        /*
        必选	类型及范围	说明
        access_token	true	string	采用OAuth授权方式为必填参数，OAuth授权后获得。
        status	true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
        */
        let params = ["access_token":CZUserViewModel.shareInstance.model!.access_token!,
            "status":publishString]
        
        SVProgressHUD.show()
        
        afn.POST("https://api.weibo.com/2/statuses/update.json", parameters: params, progress: nil , success: { (_ , JSON) -> Void in
            printLog(JSON)
            
            SVProgressHUD.dismiss()
            
            }) { (_ , error) -> Void in
                
                SVProgressHUD.showErrorWithStatus(error.description)
                
        }
        
    }
    
    //MARK:--发布图片
    private func publishPhoto(){
    
        /*
        
        上传图片并发布一条新微博
        URL
        https://upload.api.weibo.com/2/statuses/upload.json
        
        HTTP请求方式
        POST
        
        请求参数
        必选	类型及范围	说明
        access_token	false	string	采用OAuth授权方式为必填参数，其他授权方式不需要此参数，OAuth授权后获得。
        status	true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
       
       
        pic	true	binary	要上传的图片，仅支持JPEG、GIF、PNG格式，图片大小 小于5M。
        
        注意事项
        请求必须用POST方式提交，并且注意采用multipart/form-data编码方式；
        

        
        */
        
        let afn = AFHTTPSessionManager()
        
        //获取到发布微博的文字内容
        var publishString: String = ""
        
        textView.attributedText.enumerateAttributesInRange(NSMakeRange(0, textView.attributedText.length), options: []) { (data:[String : AnyObject], range:NSRange, _) -> Void in
            
            
            if let attachment = data["NSAttachment"] as? CZTextAttachment{
                printLog("\(attachment.emoticon?.chs)")
                publishString += attachment.emoticon!.chs!
                
            } else {
                printLog("这个range里的是 文字")
                let str = (self.textView.text as NSString).substringWithRange(range)
                printLog(str)
                publishString += str
            }
            
        }
        
        // 拼接参数
        let params = ["access_token":CZUserViewModel.shareInstance.model!.access_token!,
            "status":publishString]
        
        // 注意! 普通用户只能上传一张图片!!!!!!!!
        let image = photoView.allImages().first
        
        afn.POST("https://upload.api.weibo.com/2/statuses/upload.json", parameters: params, constructingBodyWithBlock: { (formdata) -> Void in
            //注意,需要把 图片放置在 formdata里
            
            /*
                参数
                1. 二进制图片
                2. 服务器的参数
                3. 文件名
                4. 文件类型
            */
            
            // 把image转换成data 第一种方法
            // 第二种方法: 画
            if let Oimage = image {
            
                //
                // UIImageJPEGRepresentation 这个方法是系统对图片提供的压缩方法
                // <#T##compressionQuality: CGFloat##CGFloat#> 是一个压缩系数 0~1
                let data = UIImageJPEGRepresentation(Oimage, 0.5)!
                
                
                formdata.appendPartWithFileData(data, name: "pic", fileName: "itcast24", mimeType: "image/jpeg")
            }
            
            
            }, progress: nil, success: { (_ , JSON) -> Void in
                print(JSON)
            }) { (_ , error) -> Void in
                print(error)
        }
        
    }
    
    //MARK:--设置TextView
    private func setupTextView(){
    
        /*
            思路一: 直接添加一个Label -- 练习一下
            思路二: 自己绘画
        
        */
        
        //添加视图
        
        view.addSubview(textView)
        
        // 设置约束
        textView.frame = view.frame
        
        //
        textView.holderString = holderString
        
        textView.font = UIFont.systemFontOfSize(15)
        
        //实现代理方法
        textView.delegate = self
        
        // 滑动textView让,键盘消失
        textView.alwaysBounceVertical = true
        textView.keyboardDismissMode = .OnDrag
        
        //添加视图
        
        textView.addSubview(photoView)
        
        //设置约束
        photoView.snp_makeConstraints { (make) -> Void in
            
            make.center.equalTo(textView.snp_center)
            
            make.width.equalTo(kUIScreenWidth - 2*CZPhotoViewMargin)
            make.height.equalTo(kUIScreenWidth - 2*CZPhotoViewMargin)
            
        }
        
    }
    
    //MARK:--设置底部ToolBar
    private func setupToolBar(){
        
        //修改toolBar的背景颜色
        toolBar.backgroundColor = UIColor.lightGrayColor()
        
        let itemSettings = [["imageName": "compose_toolbar_picture", "action": "choosePicture"],
            ["imageName": "compose_mentionbutton_background"],
            ["imageName": "compose_trendbutton_background"],
            ["imageName": "compose_emoticonbutton_background", "action": "inputEmoticon"],
            ["imageName": "compose_addbutton_background"]]
        
        //定义一个数值,来接受 items
        var items = [UIBarButtonItem]()
        
        for setting in itemSettings{
        
            //自定义button
            let button = UIButton(type: UIButtonType.Custom)
            
            
            //设置button的属性和方法
            button.setImage(UIImage(named: setting["imageName"]!), forState: UIControlState.Normal)
            //高亮的
            let imageName = setting["imageName"]!
            button.setImage(UIImage(named: "\(imageName)_highlighted"), forState: UIControlState.Highlighted)
            //button的大小一定要设置!!!!!!!
            button.sizeToFit()
            // 添加方法
            if let action = setting["action"]{
                // <#T##Selector#>
                // 当你添加方法的时候 -> "loadData" 注意  "loadData"并不代表他是字符串
                button.addTarget(self, action: Selector(action), forControlEvents: UIControlEvents.TouchUpInside)
            }
            // 赋值给UIBarButtonItem
            let item = UIBarButtonItem(customView: button)
            
            // item 添加到toolBar,一定要自己定义一个数组
            items.append(item)
            //添加弹簧
            items.append(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil))
        }
        
        //多的最后一个
        items.removeLast()
        
        toolBar.items = items
        
        //添加视图,设置约束
        view.addSubview(toolBar)
        
        toolBar.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(view.snp_left)
            make.right.equalTo(view.snp_right)
            
            self.bottomConstrant = make.bottom.equalTo(view.snp_bottom).constraint
            
            make.height.equalTo(40)
        }
    }
    
    //MARK:--选择图片的方法
   @objc private func choosePicture(){
        printLog("显示图片")
    
    /*
    case PhotoLibrary -- 相册
    case Camera         -- 相机
    case SavedPhotosAlbum -- 保存的相册
    */
    
        // 1.第一步,要判断一下,我们的手机是否能够访问 相册
    if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary){
    
        
        //如果可以方法的画,就进行页面跳转
        let picker = UIImagePickerController()
        
        // UIImagePickerController 如果你要 使用 相机的画,一定要注意修改成 Camera
        picker.sourceType = .PhotoLibrary
        
        //设置代理方法
        picker.delegate = self
        
        presentViewController(picker, animated: true, completion: { () -> Void in
            
        })
    }
    
    }
    
    var isAnimation: Bool = false
    
    //MARK:--显示表情
    @objc private func inputEmoticon(){
        printLog("显示表情")
        
        
        /*
            去设置一个标志位,来剔除 动画对 键盘的影响
        */
        // 先注销第一响应者,然后再让 textView.inputView 有视图
        isAnimation = true
        textView.resignFirstResponder()
        //取消第一响应者就会发送一个通知
        
        /*
            当 textView.inputView = nil 可以出现键盘
            当 textView.inputView = 自定义表情视图 弹出我们的表情
        */
        // 当inputView == nil的时候,我们让它显示表情键盘,否则显示系统键盘
        
        
        if textView.inputView == nil {
            //
            textView.inputView = emoticonView
        } else {
                textView.inputView = nil
        }
        
        isAnimation = false
        textView.becomeFirstResponder()
        //变成第一响应者就会发送一个通知
        
    }
    
    //MARK:--键盘改变的通知
    func changeToolBarFrame(noti: NSNotification){

        // 添加动画导致的
        /*
            如果在某一个时机,不去执行动画,就没有那样的效果
        */
        
        if isAnimation {
            return
        }
        
        
        
        
        
        
        if let info = noti.userInfo{
        
            // 需要把 NSRect 转换成CGRect .
            let endFrame = info[UIKeyboardFrameEndUserInfoKey]?.CGRectValue
            
            if endFrame?.origin.y == kUIScreenHeight {
                printLog("退出的时候")
                self.toolBar.snp_updateConstraints(closure: { (make) -> Void in
                    self.bottomConstrant = make.bottom.equalTo(self.view.snp_bottom).constraint
                })
            } else {
                printLog("弹出的时候")
                
                //修改底部toolbar的约束
                // update 和 make 是不一样的
                self.toolBar.snp_updateConstraints(closure: { (make) -> Void in
                    // 一定要注意可选项的问题
                    self.bottomConstrant = make.bottom.equalTo(self.view.snp_bottom).offset(-endFrame!.size.height).constraint
                })
            }

          
            //添加动画
            let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! NSTimeInterval
            UIView.animateWithDuration(duration, animations: { () -> Void in
                
                //想实现我们的约束动画的话,改怎么做?
                self.toolBar.layoutIfNeeded()
                
            })
        }
        
    }
    
    //MARK:--输入框里插入表情
    @objc private func inputEmoticon(noti: NSNotification){
    
        /*
            删除按钮的思路:
            1.删除按钮的通知, userInfo 传 空
            2. 需要在 if let emoticon = noti.userInfo!["emoticon"] as? CZEmoticon,判断 emoticon是否为空
            3. 如果 emoticon为空,则为删除按钮
            4. textView.deleteBackward() 用于删除

        */
        
        /*
        1.先通过通知拿到 这个表情 -> [嘻嘻]
        2.将[嘻嘻]转换成图片,展示在TextView -> 把图片添加到 NSAttributedString ,然后展示在textView.attributedText
        */
        
    
        
        // 先得获取表情
        let emoticon = noti.userInfo!["emoticon"] as! CZEmoticon
        
//        printLog(emoticon.chs)
        //显示图片
        if let png = emoticon.png {
        
            // 就把图片 显示在 TextView上
            // 记录之前的,拿到之前的 attributedText
            // 把 他转成一个可选的
            let beforeAttributedText = NSMutableAttributedString(attributedString: textView.attributedText)
            
            // 1. 创建一个附件
            let attachment = CZTextAttachment()
            attachment.emoticon = emoticon
            // 2.设置图片
            let imagePath = "\(emoticon.path!)/\(png)"
            attachment.image = UIImage(named: imagePath)
            // 第一个改: bounds
            // 表情的高度有点高: 修改 bounds , y值的修改规则和 contentOffset 一样
            attachment.bounds = CGRectMake(0, -4, textView.font!.lineHeight, textView.font!.lineHeight)
            // 3. 赋值给 Attribute
            let attribute = NSAttributedString(attachment: attachment)
            
 
           let range = textView.selectedRange
            
            beforeAttributedText.insertAttributedString(attribute, atIndex: range.location)
            
            printLog(textView.font)
            printLog(beforeAttributedText.length)
            //第二个添加: NSFontAttributeName
            beforeAttributedText.addAttributes([NSFontAttributeName: textView.font!], range: NSMakeRange(0, beforeAttributedText.length))
            
            //
            textView.attributedText = beforeAttributedText
           
            //赋值之后修改光标的位置
            textView.selectedRange = NSMakeRange(range.location+1, 0)
            
            
        }
        // emoji
        if let emoji = emoticon.emoji {
        
            // 先记录之前的 attributeText
            let beforeAttribute = NSMutableAttributedString(attributedString: textView.attributedText)
            
            let range = textView.selectedRange
            // 
            beforeAttribute.replaceCharactersInRange(NSMakeRange(range.location, 0), withString: emoji)
           
            textView.attributedText = beforeAttribute
            
        }
        
        //调用一下 TextView的代理方法 .. 强制调用代理方法
        // 思考为什么要强制解包?
        // 因为调用的这个方法 必须实现
        textView.delegate?.textViewDidChange!(textView)
    }
    
    //MARK:--销毁的方法
    deinit{
        
        //一定要记得把通知移除
       NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardDidChangeFrameNotification, object: nil)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: kNotificationEmoticonTransform, object: nil)
        printLog("控制器 88")
    }
    
    
    
    //MARK:--懒加载
    
    private lazy var textView: CZTextView = CZTextView()
    
    
    private lazy var toolBar: UIToolbar = UIToolbar()
    
    private lazy var photoView: CZPhotoView = {
    
        let photo = CZPhotoView()
        
        /*
            打破循环引用
            1.[weak self]
        2. [unowned self] self.choosePicture()
        3. 类似于OC weak var weakself = self ->  weakself?.choosePicture()
        */
        // 这个就是我们的闭包回调
        
        weak var weakself = self
        
        photo.closure = { [unowned self] ()->() in
        
            //去调用显示图片的方法
//            self.choosePicture()
//            self?.choosePicture() 1.[weak self]
//            self.choosePicture()
            weakself?.choosePicture()
            
        }
        
        return photo
    }()
    
    //表情视图
    private lazy var emoticonView: CZEmoticonView = {
    
        let emoticon = CZEmoticonView()
        
        //颜色
        emoticon.backgroundColor = UIColor.yellowColor()
        
        emoticon.frame.size = CGSizeMake(kUIScreenWidth, 216)
        
        return emoticon
    }()
}

//MARK:--UIImagePickerControllerDelegate,UINavigationControllerDelegate

extension CZPublishViewController{

    /*
        注意: 你实现了代理方法,一定要调用 dismiss 方法, 不调用的话,不能自动消失
    
    */
    // 这个方法别废弃了, 现在用这个方法还是可以的,
    // 如果实现了 这2个方法,系统优先调用 imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        
        //添加图片到图片选择器
        // 不建议大家使用属性直接添加
        // 建议 大家用方法
        photoView.addImages(image)
        
        dismissViewControllerAnimated(true) { () -> Void in
            
        }
        
    }
    
    
//    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
//    
//        print(info)
//        /*
//        info是字典类型的,我们需要获取到 UIImagePickerControllerOriginalImage 对应的值
//        
//        ["UIImagePickerControllerMediaType": public.image, 
//        "UIImagePickerControllerOriginalImage": <UIImage: 0x7fbd40413f60> size {3000, 2002} orientation 0 scale 1.000000, 
//        "UIImagePickerControllerReferenceURL": assets-library://asset/asset.JPG?id=D5BD5E90-20C1-422C-9D3E-558433A7EC2D&ext=JPG]
//        */
//        picker.dismissViewControllerAnimated(true) { () -> Void in
//            
//        }
//    }

    func imagePickerControllerDidCancel(picker: UIImagePickerController){
    
        
        print("消失")
        picker.dismissViewControllerAnimated(true) { () -> Void in
            
        }
    }
    
}

//MARK:--TextViewDelagate
extension CZPublishViewController{

    func textViewDidChange(textView: UITextView) {
        
        //
        if textView.hasText() {
            // 不显示占位符
            self.textView.holderString = ""
            
            
        } else {
            // 显示占位符
            self.textView.holderString = holderString
        }
        
        //重绘
        self.textView.setNeedsDisplay()
        
        navigationItem.rightBarButtonItem?.enabled = textView.hasText()
        
        
    }
    
}
